import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:share_fit/app/models/home/stress_model.dart';
import 'package:share_fit/app/tools/color_const.dart';

class StressBarChart extends StatefulWidget {
  StressBarChart({super.key, List<StressModel>? modelList}) : data = modelList ?? [];

  final List<StressModel> data;

  @override
  State<StatefulWidget> createState() => _StressBarChartState();
}

class _StressBarChartState extends State<StressBarChart> {
  final double width = 7;

  var titles = <dynamic>{};

  int touchedGroupIndex = -1;
  int touchedGroupRodIndex = -1;

  @override
  Widget build(BuildContext context) {
    titles = widget.data.map((e) => e.calendar).toSet();

    return AspectRatio(
      aspectRatio: 1.70,
      child: Padding(
        padding: EdgeInsets.only(top: 70.h, bottom: 50.h, left: 20.w, right: 60.w),
        child: BarChart(
          BarChartData(
            maxY: 100,
            barTouchData: barTouchData,
            titlesData: titlesData,
            borderData: borderData,
            barGroups: makeGroupDataList(),
            gridData: gridData,
          ),
        ),
      ),
    );
  }

  get barTouchData => BarTouchData(
        handleBuiltInTouches: false,
        longPressDuration: const Duration(milliseconds: 200),
        touchCallback: (FlTouchEvent event, response) {
          if (event.isInterestedForInteractions && response != null && response.spot != null) {
            setState(() {
              touchedGroupIndex = response.spot!.touchedBarGroupIndex;
              touchedGroupRodIndex = response.spot!.touchedRodDataIndex;
            });
          } else {
            setState(() {
              touchedGroupIndex = -1;
              touchedGroupRodIndex = -1;
            });
          }
        },
        touchTooltipData: BarTouchTooltipData(
          tooltipBgColor: Colors.grey.withOpacity(.3),
          tooltipPadding: EdgeInsets.all(10.w),
          getTooltipItem: (BarChartGroupData group, int groupIndex, BarChartRodData rod, int rodIndex) {
            StressModel model = widget.data[touchedGroupIndex];
            return BarTooltipItem(
              '${model.tooltipText}${model.calendarTime}',
              TextStyle(
                fontSize: 36.sp,
                shadows: const [Shadow(color: Colors.black26, blurRadius: 12)],
              ),
            );
          },
        ),
      );

  get titlesData => FlTitlesData(
        show: true,
        rightTitles: const AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
        topTitles: const AxisTitles(
          sideTitles: SideTitles(showTitles: false),
        ),
        bottomTitles: AxisTitles(
          sideTitles: SideTitles(
            showTitles: true,
            getTitlesWidget: bottomTitles,
          ),
        ),
        leftTitles: AxisTitles(
          drawBelowEverything: true,
          sideTitles: SideTitles(
            showTitles: true,
            getTitlesWidget: leftTitles,
            reservedSize: 30,
            interval: 1,
          ),
        ),
      );

  get borderData => FlBorderData(
        show: true,
        border: Border(
          left: BorderSide(width: 1.w, color: const Color(0xff37434d)),
          bottom: BorderSide(width: 1.w, color: const Color(0xff37434d)),
        ),
      );

  get gridData => FlGridData(
        show: true,
        drawHorizontalLine: true,
        drawVerticalLine: false,
        horizontalInterval: 25,
        getDrawingVerticalLine: (value) => FlLine(
          color: ColorConst.secondaryBgColor,
          strokeWidth: 1,
          dashArray: [8, 4],
        ),
      );

  Widget leftTitles(double value, TitleMeta meta) {
    String text;
    switch (value.toInt()) {
      case 1:
        text = '0';
        break;
      case 25:
        text = '25';
      case 50:
        text = '50';
      case 75:
        text = '75';
        break;
      case 100:
        text = '100';
        break;
      default:
        return Container();
    }
    return Container(
      padding: EdgeInsets.only(right: 10.w),
      child: Text(
        text,
        style: TextStyle(color: ColorConst.secondaryFontColor, fontSize: 36.sp),
        textAlign: TextAlign.center,
      ),
    );
  }

  Widget bottomTitles(double value, TitleMeta meta) {
    String text;
    int len = titles.length;
    int idx = value.toInt();

    if (len > 0) {
      if (len == 7) {
        text = idx < len ? titles.elementAt(idx) : '';
      } else {
        if (idx == 0) {
          text = titles.first;
        } else if (idx == len ~/ 2) {
          text = titles.elementAt(len ~/ 2);
        } else if (idx == len - 1) {
          text = titles.last;
        } else {
          text = '';
        }
      }
    } else {
      text = '';
    }

    return SideTitleWidget(
      axisSide: meta.axisSide,
      child: Text(text, style: TextStyle(color: ColorConst.secondaryFontColor, fontSize: 36.sp)),
    );
  }

  List<BarChartGroupData> makeGroupDataList() {
    List<BarChartGroupData> groups = [];
    for (int i = 0; i < widget.data.length; i++) {
      BarChartGroupData data = BarChartGroupData(
        x: i,
        barsSpace: 3.w,
        barRods: [
          BarChartRodData(
            toY: widget.data[i].pressureValue!.toDouble(),
            color: getColor(widget.data[i].level!),
            width: 20.w,
            borderRadius: BorderRadius.only(topLeft: Radius.circular(7.r), topRight: Radius.circular(7.r)),
          )
        ],
        showingTooltipIndicators: touchedGroupIndex == i ? [touchedGroupRodIndex] : [],
      );

      groups.add(data);
    }
    return groups;
  }

  /// 获取当前压力文本
  Color getColor(int level) {
    if (level == 1) {
      return const Color.fromRGBO(19, 208, 255, 1);
    } else if (level == 2) {
      return Colors.greenAccent;
    } else if (level == 3) {
      return const Color.fromRGBO(181, 124, 255, 1);
    } else if (level == 4) {
      return Colors.red.withOpacity(.7);
    } else {
      return Colors.transparent;
    }
  }
}
